﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _19.备忘录模式
{
    class Program
    {
        static void Main(string[] args)
        {
            var persons = new List<ContactPerson>
        {
                new ContactPerson { Name= "Learning Hard", MobileNum = "123445"},
                new ContactPerson { Name = "Tony", MobileNum = "234565"},
                new ContactPerson { Name = "Jock", MobileNum = "231455"}
            };
            var mobileOwner = new MobileOwner(persons);
            mobileOwner.Show();

            // 创建备忘录并保存备忘录对象
            var caretaker = new Caretaker { ContactM = mobileOwner.CreateMemento() };

            Console.WriteLine("----移除最后一个联系人--------");// 更改发起人联系人列表
            mobileOwner.ContactPersons.RemoveAt(2);
            mobileOwner.Show();

            Console.WriteLine("-------恢复联系人列表------");// 恢复到原始状态
            mobileOwner.RestoreMemento(caretaker.ContactM);
            mobileOwner.Show();

            Console.Read();
 
        }
    }
    public class ContactPerson
    {
        public string Name { get; set; }
        public string MobileNum { get; set; }
    }
    public class MobileOwner// 发起人
    {
        public List<ContactPerson> ContactPersons { get; set; }// 发起人需要保存的内部状态
        public MobileOwner(List<ContactPerson> persons)
        {
            ContactPersons = persons;
        }
        public ContactMemento CreateMemento()// 创建备忘录，将当期要保存的联系人列表导入到备忘录中
        {
            // 这里也应该传递深拷贝，new List方式传递的是浅拷贝，
            // 因为ContactPerson类中都是string类型,所以这里new list方式对ContactPerson对象执行了深拷贝
            // 如果ContactPerson包括非string的引用类型就会有问题，所以这里也应该用序列化传递深拷贝
            return new ContactMemento(new List<ContactPerson>(this.ContactPersons));
        }
        public void RestoreMemento(ContactMemento memento)// 将备忘录中的数据备份导入到联系人列表中
        {
            //应该传递contactPersonBack的深拷贝，深拷贝可以使用序列化来完成
            ContactPersons = memento.ContactPersonBack;
        }
        public void Show()
        {
            Console.WriteLine("联系人列表中有{0}个人，他们是:", ContactPersons.Count);
            foreach (ContactPerson p in ContactPersons)
            {
                Console.WriteLine("姓名: {0} 号码为: {1}", p.Name, p.MobileNum);
            }
        }
    }
    public class ContactMemento// 备忘录
    {
        public List<ContactPerson> ContactPersonBack; // 保存发起人的内部状态
        public ContactMemento(List<ContactPerson> persons)
        {
            ContactPersonBack = persons;
        }
    }
    public class Caretaker// 管理角色
    {
        public ContactMemento ContactM { get; set; }
    }
 
}
